package com.fablesoft.projectdatacollect.http;

import android.graphics.Bitmap;
import android.text.TextUtils;
import android.util.Log;

import com.fablesoft.projectdatacollect.MyApplication;
import com.fablesoft.projectdatacollect.bean.BaseResponse;
import com.fablesoft.projectdatacollect.bean.ItemFingerprint;
import com.fablesoft.projectdatacollect.bean.ItemMaterial;
import com.fablesoft.projectdatacollect.util.BitmapUtil;
import com.fablesoft.projectdatacollect.util.CommonUtils;
import com.fablesoft.projectdatacollect.util.Config;
import com.fablesoft.projectdatacollect.util.Log4jUtil;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MultipartBody;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class RequestUpload<T> extends BaseRequest {

    private String fileKey;
    private List<String> fileNames;
    private List<T> files;
    private T file;
    private String fileName;

    /**
     * 单文件上传
     *
     * @param url
     * @param params
     * @param fileKey
     * @param fileName
     * @param file
     * @param clazz
     * @param listener
     */
    public RequestUpload(String url, Map<String, Object> params, String fileKey, String fileName, T file, Class clazz, HttpListener listener) {
        this.url = url;
        this.params = params;
        this.fileKey = fileKey;
        this.fileName = fileName;
        this.file = file;
        this.clazz = clazz;
        this.listener = listener;
    }

    /**
     * 多文件上传
     *
     * @param url
     * @param params
     * @param fileKey
     * @param fileNames
     * @param files
     * @param clazz
     * @param listener
     */
    public RequestUpload(String url, Map<String, Object> params, String fileKey, List<String> fileNames, List<T> files, Class clazz, HttpListener listener) {
        this.url = url;
        this.params = params;
        this.fileKey = fileKey;
        this.fileNames = fileNames;
        this.files = files;
        this.clazz = clazz;
        this.listener = listener;
    }

    /**
     * 多文件上传
     *
     * @param url
     * @param params
     * @param fileKey
     * @param files
     * @param clazz
     * @param listener
     */
    public RequestUpload(String url, Map<String, Object> params, String fileKey, List<T> files, Class clazz, HttpListener listener) {
        this.url = url;
        this.params = params;
        this.fileKey = fileKey;
        this.files = files;
        this.clazz = clazz;
        this.listener = listener;
    }

    public void sendFilesRequest() {
        if (files == null || files.size() <= 0) {
            Log4jUtil.d("文件为空");
            return;
        }
        MultipartBody.Builder builder = new MultipartBody.Builder();
        builder.setType(MultipartBody.FORM);
        //遍历map中所有参数到builder
        if (params != null) {
            for (String key : params.keySet()) {
                builder.addFormDataPart(key, params.get(key).toString());
            }
        }
        //遍历paths中所有图片绝对路径到builder，并约定key如“upload”作为后台接受多张图片的key
        ItemFingerprint itemFingerprint;
        ItemMaterial itemMaterial;
        for (int i = 0; i < files.size(); i++) {
            T file = files.get(i);
            if (file instanceof File) {
                builder.addFormDataPart(fileKey, fileNames.get(i), RequestBody.create(MEDIA_TYPE_JPG, (File) file));
            } else if (file instanceof ItemFingerprint) {
                itemFingerprint = (ItemFingerprint) file;
                builder.addFormDataPart(fileKey, itemFingerprint.getFileName(), RequestBody.create(MEDIA_TYPE_JPG, itemFingerprint.getImageBytes()));
            } else if (file instanceof ItemMaterial) {
                itemMaterial = (ItemMaterial) file;
                builder.addFormDataPart(fileKey, itemMaterial.getFileName(), RequestBody.create(MEDIA_TYPE_JPG, new File(itemMaterial.getLocalPath())));
            }
        }
        //构建请求体
        RequestBody requestBody = builder.build();
        Request.Builder requestBuilder = new Request.Builder();
        requestBuilder.url(url);
        requestBuilder.header("Cookie", MyApplication.getInstance().getSessionId()).header(Config.CLIENT_TYPE_KEY, Config.CLIENT_TYPE_VALUE);
        requestBuilder.post(requestBody);
        Request request = requestBuilder.build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.d(CommonUtils.TAG_UPLOAD, "excetion = " + e.toString());
                listener.onRequestFinish(null);
                Log4jUtil.e(e.toString());
                call.cancel();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response == null || response.body() == null) {
                    listener.onRequestFinish(null);
                    call.cancel();
                    return;
                }
                String result = response.body().string();
                CommonUtils.showLogCompletion(result, 2 * 1024);
                try {
                    BaseResponse baseResponse = JsonUtil.getResponse(result, clazz);
                    if ("403".equals(baseResponse.getCode())) {
                        listener.onNotLogin(baseResponse);
                    } else {
                        listener.onRequestFinish(baseResponse);
                    }
                } catch (Exception e) {
                    Log4jUtil.e(e.toString());
                    e.printStackTrace();
                } finally {
                    Log4jUtil.d(result);
                    call.cancel();
                }
            }
        });
    }

    public void sendFileRequest() {
        if (file == null || TextUtils.isEmpty(fileName)) {
            Log4jUtil.d("文件为空");
            return;
        }
        MultipartBody.Builder builder = new MultipartBody.Builder();
        builder.setType(MultipartBody.FORM);
        if (params != null) {
            for (String key : params.keySet()) {
                builder.addFormDataPart(key, params.get(key).toString());
            }
        }
        if (file instanceof File) {
            builder.addFormDataPart(fileKey, fileName, RequestBody.create(MEDIA_TYPE_JPG, (File) file));
        } else if (file instanceof Bitmap) {
            builder.addFormDataPart(fileKey, fileName, RequestBody.create(MEDIA_TYPE_JPG, BitmapUtil.bitmapToBytes((Bitmap) file)));
        } else if (file instanceof byte[]) {
            builder.addFormDataPart(fileKey, fileName, RequestBody.create(MEDIA_TYPE_JPG, (byte[]) file));
        }

        //构建请求体
        RequestBody requestBody = builder.build();
        Request.Builder requestBuilder = new Request.Builder();
        requestBuilder.url(url);
        requestBuilder.header("Cookie", MyApplication.getInstance().getSessionId());
        requestBuilder.post(requestBody);
        Request request = requestBuilder.build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.d(CommonUtils.TAG_UPLOAD, "excetion = " + e.toString());
                listener.onRequestFinish(null);
                Log4jUtil.e(e.toString());
                call.cancel();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response == null || response.body() == null) {
                    listener.onRequestFinish(null);
                    call.cancel();
                    return;
                }
                String result = response.body().string();
                CommonUtils.showLogCompletion(result, 2 * 1024);
                try {
                    BaseResponse baseResponse = JsonUtil.getResponse(result, clazz);
                    if ("403".equals(baseResponse.getCode())) {
                        listener.onNotLogin(baseResponse);
                    } else {
                        listener.onRequestFinish(baseResponse);
                    }
                } catch (Exception e) {
                    Log4jUtil.e(e.toString());
                    e.printStackTrace();
                } finally {
                    Log4jUtil.d(result);
                    call.cancel();
                }
            }
        });
    }

}
